package org.jackysoft.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.annotation.Resource;

import org.jackysoft.entity.ActionNode;
import org.jackysoft.entity.ActionsNode;
import org.jackysoft.entity.ConditionsResultNode;
import org.jackysoft.entity.JoinNode;
import org.jackysoft.entity.OsStep;
import org.jackysoft.entity.ResultNode;
import org.jackysoft.entity.ResultsNode;
import org.jackysoft.entity.SplitNode;
import org.jackysoft.entity.StepNode;
import org.jackysoft.entity.WorkflowNode;
import org.jackysoft.service.WorkflowNodeService;
import org.springframework.stereotype.Component;

@Component
public final class WorkflowUtil {

	protected @Resource
	WorkflowNodeService nodeService;

	

	public SortedMap<Integer, String> getStepInfomation(WorkflowNode wdes) {
		final SortedMap<Integer, String> steps = new TreeMap<Integer, String>(
				new Comparator<Integer>() {

					@Override
					public int compare(Integer o1, Integer o2) {
						if (o1 > o2)
							return 1;
						else if (o1 == o2)
							return 0;
						else
							return -1;

					}

				});
		for (StepNode step : wdes.getSteps().getSteps()) {

			steps.put(step.getId(), step.getName());
		}

		return steps;
	}

	/**
	 * 功能:根据actionId 获取action 定义所在 的Step id
	 * 
	 * @param workflow
	 *            工作流对象
	 * @param actionId
	 *            活动编号
	 * @param workflowId
	 *            工作流编号
	 * @return 步骤Id
	 */
	public OsStep getStepIdByActionId(int actionId, String workflow, List csteps) {
		OsStep tstep = null;
		// 遍历当前步骤 找出与包含活动参数相等的步骤
		outer: for (Object so : csteps) {
			OsStep step = (OsStep) so;

			StepNode sdesc = nodeService.getStepNode(Integer.valueOf(step.getId()+""), workflow);
			;
			ActionsNode asn = sdesc.getActions();
			if (asn == null)
				return null;
			Collection<ActionNode> actions = asn.getActions();
			for (ActionNode adesc : actions) {
				ActionNode asc = adesc;
				if (asc.getId() == actionId) {
					tstep = step;
					break outer;
				}
			}
		}
		return tstep;
	}

	/**
	 * 功能:根据actionId 获得 该action 的下步List<StepDescriptor>
	 * 
	 * @param workflow
	 *            工作流对象
	 * @param actionId
	 *            活动编号
	 * @param workflowId
	 *            工作流编号
	 * @return 步骤描述列表list;
	 */

	public List<StepNode> getNextSteps(String workflow, int actionId) {
		List<StepNode> nextSteps = new ArrayList<StepNode>();
		ActionNode adesc = nodeService.getActionNode(actionId,				workflow);
		if (adesc == null)
			return nextSteps;
		ResultsNode rsts = adesc.getResultsNode();
		ResultNode uresult = rsts.getUnconditionalResult();
		Collection<ConditionsResultNode> cresults = rsts
				.getConditionalResults();
		nextSteps.addAll(parseStep(workflow, uresult));
		nextSteps.addAll(parseStep(workflow, cresults));

		return nextSteps;
	}

	/**
 	 * 
 	 */
	private List<StepNode> parseStep(String wfname, ResultNode results) {
		List<StepNode> nextSteps = new ArrayList<StepNode>();
		if (null == results)
			return nextSteps;
		else {
			if (results.getStep() != 0) {
				nextSteps.add(getStepNode(wfname, results.getStep()));
				return nextSteps;
			} else if (results.getJoin() != 0) {
				JoinNode jdesc = getJoinNode(wfname, results.getJoin());
				ResultNode trs = jdesc.getResult();
				nextSteps.add(getStepNode(wfname, trs.getStep()));
				return nextSteps;
			} else if (results.getSplit() != 0) {
				SplitNode sdesc = getSplitNode(wfname, results.getSplit());
				Collection<ResultNode> trs = sdesc.getResults();
				for (ResultNode o : trs) {
					nextSteps.add(getStepNode(wfname, o.getStep()));
				}
				return nextSteps;
			}
		}
		return nextSteps;
	}

	public StepNode getStepNode(String wfname, int id) {
		return nodeService.getStepNode(id, wfname);
	}

	public JoinNode getJoinNode(String wfname, int id) {
		return nodeService.getJoinNode(id, wfname);
	}

	public SplitNode getSplitNode(String wfname, int step) {
		return nodeService.getSplitNode(step, wfname);
	}

	private <T extends ResultNode> List<StepNode> parseStep(String wfname,
			Collection<T> results) {
		List<StepNode> nextSteps = new ArrayList<StepNode>();
		if (null == results)
			return nextSteps;
		else {
			for (ResultNode result : results)
				nextSteps.addAll(parseStep(wfname, result));

		}
		return nextSteps;
	}

}
